/******************************************************************************
 * Copyright (C) 2025 Engineer Liu Si
 * 
 * All Rights Reserved.
 * 
 * @file bsp_key.c
 * 
 * @par dependencies 
 * - bsp_key.h
 * 
 * @author liusi
 * 
 * @brief Provide the HAL APIs of Key and corresponding opetions.
 * 
 * Processing flow:
 * 
 * call directly.
 * 
 * @version V1.0 2025-09-27
 *
 * @note 1 tab == 4 spaces!
 * 
 *****************************************************************************/
#include "bsp_key.h"

//******************** Thread_Func ***********************//
osThreadId_t key_TaskHandle;
const osThreadAttr_t key_Task_attributes = {
  .name = "key_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal2,
};

//******************** Thread_Func ***********************//

//******************* Queue_Handler **********************//
QueueHandle_t key_queue;

//******************* Queue_Handler **********************//
/**
 * @brief Instantiates the bsp_led_handler_t target.
 * 
 * Steps:
 *  1.doing the specific operations.
 *  
 * 
 * @param[in] void
 * @return led_handler_status_t : Status of the function.
 * 
 * */
key_status_t key_scan( key_press_status_t * key_value )
{
	key_press_status_t key_status_value = KEY_NOT_PRESSED;
	
	if( HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET )
	{
		key_status_value = KEY_PRESSED;
	}
	else
	{
		key_status_value = KEY_NOT_PRESSED;		    
	}

	if(   ( KEY_PRESSED     == key_status_value ) 
		||( KEY_NOT_PRESSED == key_status_value )
		)
	{
		*key_value = key_status_value;
		return KEY_OK;
	}

	printf("Key is scan Timeout \r\n");
	return KEY_ERRORTIMEOUT;
}

/**
 * @brief Key_Task_Func for thread to run.
 * 
 * Steps:
 *  1.doing the specific operations.
 *  
 * 
 * @param[in] void
 * @return led_handler_status_t : Status of the function.
 * 
 * */
void Key_Task_Func(void *argument)
{
	key_status_t       key_ret       =          KEY_OK;
	key_press_status_t key_status    = KEY_NOT_PRESSED;
	uint32_t           key_press_cnt =               0;
	uint32_t  key_continue_press_cnt =               0;
	uint32_t     key_press_time_flag =             300;
	uint32_t          key_shake_flag =               0;

	key_queue = xQueueCreate( 10, sizeof( key_press_status_t ) );
	if( key_queue != 0 )
	{
		printf("key_queue is create success \r\n");
	}
	for(;;)
	{			
		key_ret = key_scan( &key_status );
			
		if( KEY_OK == key_ret )
		{
			if ( KEY_PRESSED == key_status )
			{
				 key_press_cnt++;
                 key_shake_flag = 1;
				 key_press_time_flag = 20;
			}
			else
			{
				if (   ( key_press_cnt > 2  ) 
				     &&( key_press_cnt < 30 )
					)
				{		
					key_continue_press_cnt++;     
				}
				else if ( key_press_cnt >= 30 ) 
				{
					key_status = KEY_LONG_PRESSED;
					if ( pdPASS == xQueueSend( key_queue, &key_status, 0) )
					{
						 printf("send long press successfully \r\n");
					}					
				}
				else
				{			
					if(  ( key_shake_flag )
					   &&( pdFALSE != key_press_cnt )
				      )
			        {
						printf("key_press_cnt = %d\r\n" , key_press_cnt);
					     printf("send error because shake \r\n");
						 key_shake_flag = 0;
					}		
				}
				key_press_cnt = 0;


				if ( key_press_time_flag == 1)
				{
					switch (key_continue_press_cnt)
					{
					case 1:			
						key_status = KEY_PRESSED;
						if ( pdPASS == xQueueSend( key_queue, &key_status, 0) )
						{
								printf("send one press successfully \r\n");
						}
						break;
					case 2:
						key_status = KEY_TWO_PRESSED;
						if ( pdPASS == xQueueSend( key_queue, &key_status, 0) )
						{
								printf("send two press successfully \r\n");
						}
						break;
					case 3:
						key_status = KEY_THREE_PRESSED;
						if ( pdPASS == xQueueSend( key_queue, &key_status, 0) )
						{
								printf("send three press successfully \r\n");
						}						
						break;
					case 4:
						key_status = KEY_FOUR_PRESSED;
						if ( pdPASS == xQueueSend( key_queue, &key_status, 0) )
						{
								printf("send four press successfully \r\n");
						}						
						break;			
					default:
						break;
					}	
					key_continue_press_cnt = 0;
			    }	
				
				
			}
		}
		else
		{
                printf("Key is Task Timeout \r\n");
		}

		key_press_time_flag--;
		if( key_press_time_flag == 0)
		{ key_press_time_flag = 1;}

		osDelay(10);
	}
}

